package com.obas.business.scriptmanagement.util;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ease.common.util.Detect;
import com.ease.document.freemarker.FreeMarkerUtil;
import com.obas.business.common.vo.AtMessage;
import com.obas.business.common.vo.TestContext;
import com.obas.business.scriptmanagement.vo.ScriptAtomationArg;
import com.obas.business.scriptmanagement.vo.ScriptAtomationPart;
import com.obas.business.scriptmanagement.vo.ScriptStatement;
import com.obas.business.scriptmanagement.vo.ScriptVerification;
import com.obas.model.business.ParameterType;
import com.obas.monitor.AtCommand;
import com.obas.monitor.TestContextManager;

import flex.messaging.io.amf.ASObject;

public abstract class ScriptStatementConvertor extends Detect {

	public static String CONSTLITERAL = "___constliteral___";

	@SuppressWarnings("unchecked")
	public static ScriptStatement asScriptStatement(AtMessage atMessage) {

		ScriptStatement scriptStatement = new ScriptStatement();
		//
		ASObject p = (ASObject) (atMessage.getParam());
		if (atMessage.getCommand() == AtCommand.Verification) {
			scriptStatement.setCommand(AtCommand.Verification);
		}
		// StringBuffer result = new StringBuffer("<" + atMessage.getId() + ", " + atMessage.getTime() + ", ");

		Object propList = p.get("propList");
		if (null != propList) {
			ASObject prop = null;
			if (propList instanceof Object[]) {
				prop = (ASObject) ((Object[]) propList)[0];
			} else if (propList instanceof List<?>) {
				prop = (ASObject) ((List<?>) propList).get(0);
			} else {
				prop = (ASObject) propList;
			}
			ScriptVerification scriptVerification = new ScriptVerification();
			scriptStatement.setScriptVerification(scriptVerification);

			scriptVerification.setName(asString(prop.get("name")));
			scriptVerification.setValue(asString(prop.get("value")));
		}

		ASObject locator = (ASObject) (p.get("locator"));
		if (locator != null) {
			Object[] parts = (Object[]) locator.get("parts");
			String path = "";
			int len = parts.length;
			for (int i = 0; i < len; i++) {
				Map<String, String> part = (Map<String, String>) parts[i];
				ScriptAtomationPart scriptAtomationPart = new ScriptAtomationPart();
				String automationName = part.get("automationName");
				scriptAtomationPart.setAutomationName(automationName);
				String automationClassName = part.get("automationClassName");
				scriptAtomationPart.setAutomationClassName(automationClassName);
				if (part.containsKey("automationIndex")) {
					String automationIndex = part.get("automationIndex");
					scriptAtomationPart.setAutomationIndex(automationIndex);
				}
				path += automationClassName + "(" + automationName + ")->";
				if (i == len - 1) {
					scriptStatement.setAutomationName(automationName);
				}
				scriptStatement.addScriptAtomationPart(scriptAtomationPart);
			}
			// result.append(path.substring(0, path.length() - 2));
		}
		String method = (String) p.get("method");
		scriptStatement.setMethod(method);

		// result.append(", " + method + "(");
		if (method != null) {
			Object[] args = (Object[]) (p.get("args"));
			if (args != null && args.length > 0) {
				String value = "";

				for (int i = 0; i < args.length; i++) {
					Object arg = args[i];
					if (arg instanceof ASObject) {
						value += ((ASObject) arg).get(CONSTLITERAL) + ",";
					} else {
						value += arg.toString() + ",";
					}					
				}
				value = value.substring(0, value.length() - 1);
				
				ScriptAtomationArg scriptAtomationArg = new ScriptAtomationArg();
				scriptAtomationArg.setValue(value);
				scriptStatement.addScriptAtomationArg(scriptAtomationArg);
				
				// result.append(value + ")");
				// scriptStatement.setArgs(value);
			} else {
				// result.append(")");
			}
		}
		// result.append(">\n\n");

		ASObject flexBitmapData = (ASObject) (p.get("extraInfo"));
		if(null!=flexBitmapData) {
//			scriptStatement.setScreenWidth(Integer.parseInt(asString(flexBitmapData.get("width"))));
//			scriptStatement.setScreenHeight(Integer.parseInt(asString(flexBitmapData.get("height"))));
//			scriptStatement.setScreenshot(( byte[])flexBitmapData.get("data"));
		}
		
		String appId = ((Map<String, Object>) (atMessage.getParam())).get("pageId") + "";
		scriptStatement.setAppId(appId);

		TestContext testContext = TestContextManager.getTestContext(appId);
		scriptStatement.setTestcaseScriptId(testContext.scriptId);

		// Map<String, Object> param = new HashMap<String, Object>();
		// param.put("recordingText", result.toString());

		return scriptStatement;
	}

	public static String asParameterizedScript(ScriptStatement scriptStatement,ParameterType parameterType ) {
		return asScript(scriptStatement, parameterType, true);

	}

	public static String asScript(ScriptStatement scriptStatement) {
		return asScript(scriptStatement, null, false);
	}

	private static String asScript(ScriptStatement scriptStatement, ParameterType parameterType, boolean parameterized) {

		Map<String, Object> object = new HashMap<String, Object>();
		object.put("scriptStatement", scriptStatement);
		object.put("parameterized", parameterized);
		object.put("parameterType", parameterType);
		
		String script = FreeMarkerUtil.processFile(ScriptStatementConvertor.class, "script.statement.ftl", object);
		return script;
	}

	@Deprecated
	public static String toScriptString(AtMessage msg, boolean parameterized) {
		ASObject p = (ASObject) (msg.getParam());
		StringBuffer result = new StringBuffer();
		if (msg.getCommand() == AtCommand.Verification) {
			result.append("verifyEqual(");
			ASObject locator = (ASObject) (p.get("locator"));
			if (locator != null) {
				result.append(getLocatorStr(locator));
			}
			Object propList = p.get("propList");
			ASObject prop = null;
			if (propList instanceof Object[]) {
				prop = (ASObject) ((Object[]) propList)[0];
			} else if (propList instanceof List<?>) {
				prop = (ASObject) ((List<?>) propList).get(0);
			} else {
				prop = (ASObject) propList;
			}

			result.append("." + prop.get("name"));
			result.append(", ");
			result.append(prop.get("value"));
			result.append(")");
		} else {
			ASObject locator = (ASObject) (p.get("locator"));
			if (locator != null) {
				result.append(getLocatorStr(locator));
			}

			String method = (String) p.get("method");
			result.append(", " + method + "(");
			if (method != null) {
				Object[] args = (Object[]) (p.get("args"));
				if (args != null && args.length > 0) {
					String value = "";
					for (int i = 0; i < args.length; i++) {
						Object arg = args[i];
						if (arg instanceof ASObject) {
							value += ((ASObject) arg).get(CONSTLITERAL) + ",";
						} else {
							value += arg.toString() + ",";
						}
					}
					result.append(value.substring(0, value.length() - 1) + ")");
				} else {
					result.append(")");
				}
			}
		}
		return result.toString();
	}

	@SuppressWarnings("unchecked")
	@Deprecated
	public static String getLocatorStr(ASObject locator) {
		if (locator != null) {
			Object[] parts = (Object[]) locator.get("parts");
			StringBuffer path = new StringBuffer();
			for (int i = 0; i < parts.length; i++) {
				Map<String, String> part = (Map<String, String>) parts[i];
				path.append(part.get("automationClassName") + "(" + part.get("automationName"));
				if (part.containsKey("automationIndex")) {
					path.append(", " + part.get("automationIndex"));
				}
				path.append(")");
				if (i != parts.length - 1) {
					path.append("->");
				}
			}
			return path.toString();
		}
		return null;
	}

	public static void main(String[] args) {
		ScriptStatement scriptStatement = new ScriptStatement();
		String string = ScriptStatementConvertor.asParameterizedScript(scriptStatement,null);
		System.out.println(string);

		string = ScriptStatementConvertor.asScript(scriptStatement);
		System.out.println(string);
	}
}
